📌 Что это за проект
Перед нами не просто праздничная веб-страница, а полноценная демонстрация работы сервера, которая одновременно:
- показывает, что сервер онлайн
- работает по HTTPS
- умеет определять IP посетителя
- красиво анимирована (снег, гирлянды, ёлка, фейерверки)
- адаптируется под ПК и смартфоны
- не использует ни одной сторонней библиотеки
Проект демонстрирует связку: Frontend (HTML / CSS / JS / Canvas) + Backend-логика на уровне Nginx.
🧱 Архитектура проекта
Проект намеренно минималистичен и состоит всего из двух файлов:
index.html → интерфейс и анимации
mysite.txt → конфигурация сервера Nginx
Общая схема работы
Пользователь
↓
HTTPS (Nginx)
↓
sub_filter / маршруты
↓
index.html
↓
Canvas + JavaScript
- нет БД
- нет PHP
- нет Node.js
- максимум эффекта — минимум технологий
🧩 Файл index.html — лицо проекта
Это единственный файл, который загружается браузером.
Базовая HTML-структура
```html
<!DOCTYPE html>
<html lang="ru">
<head>...</head>
<body>...</body>
</html>
Страница содержит:
-
заголовок «Сервер работает»
-
подзаголовок (который сервер может переписать)
-
таймер до Нового года
-
Canvas с ёлкой
-
Canvas с гирляндами
-
слой снега поверх всего
🎨 Визуальный стиль (CSS)
🌌 Фон
background: radial-gradient(circle at top,#0b2a55,#000814 70%);
-
создаёт эффект ночного неба
-
не требует изображений
-
быстро загружается
-
отлично смотрится на любых экранах
📱 Адаптивность
@media (max-width: 480px) { ... }
При маленьком экране:
-
гирлянда становится вертикальной
-
контент смещается вправо
-
таймер уплотняется
-
интерфейс остаётся читаемым
💡 Важно:
Адаптация выполнена чисто через CSS, без JS-костылей.
⏱ Таймер до Нового года
HTML
<b id="d"></b> дней
<b id="h"></b> часов
<b id="m"></b> минут
<b id="s"></b> секунд
JavaScript-логика
function nextNewYear() {
const now = new Date();
let y = now.getFullYear();
if (now >= new Date(y,0,1)) y++;
return new Date(y,0,1);
}
Почему это грамотное решение
-
учитывается локальный часовой пояс
-
не нужен сервер
-
таймер продолжает работать даже офлайн
-
нет зависимости от API и внешних источников
❄️ Снег
Снег реализован через DOM + CSS-анимации.
for (let i = 0; i < 170; i++) {
const s = document.createElement('span');
}
-
170 снежинок
-
разная скорость и размер
-
анимация через
@keyframes -
минимальная нагрузка на JS
📌 Визуально создаёт «живую открытку».
💡 Гирлянды (Canvas)
Используется HTML5 Canvas.
Два режима работы
-
Горизонтальный — для ПК
-
Вертикальный — для смартфонов
if (isVertical) {
drawVerticalGarland(t);
} else {
drawHorizontalGarland(t);
}
Что реализовано
-
волнистый провод (синусоида)
-
мигающие лампочки
-
мягкое свечение (
shadowBlur) -
разные фазы мигания
📌 Один алгоритм — две геометрии.
🎄 Ёлка (Canvas)
Ёлка не картинка, а полностью рисуется кодом.
Состав ёлки
-
ветки (процедурная генерация)
-
гирлянда с миганием
-
огни с фазами
-
ствол
-
звезда с сиянием
-
реакция на клик
canvas.addEventListener('click', () => clickWave = 1);
💡 При клике по ёлке запускается волна усиленного свечения, которая постепенно затухает.
🎆 Фейерверки
Запускаются при наступлении Нового года.
-
частицы с физикой
-
разлёт, затухание, исчезновение
-
Canvas +
requestAnimationFrame
Используются как праздничное событие, а не постоянная анимация.
🎆 Фейерверки
Запускаются при наступлении Нового года.
-
частицы с физикой
-
разлёт, затухание, исчезновение
-
Canvas +
requestAnimationFrame
Используются как праздничное событие, а не постоянная анимация.
🎨 Логика анимаций: как это работает изнутри
Этот проект построен не на «готовых эффектах», а на простых математических принципах, которые в сумме дают живую анимацию. Ниже — разбор ключевых частей.
🎄 Принцип построения ёлки (Canvas)
Ёлка не рисуется линиями или треугольниками.
Она собирается из множества маленьких веток, размещённых по определённому правилу.
1. Вертикальная структура
for (let y = 60; y < 440; y += 6) {
...
}
-
ось
yидёт сверху вниз -
шаг 6px создаёт плотную крону
-
верх узкий, низ широкий
Это формирует силуэт ёлки.
2. Расширение к низу (ширина кроны)
const w = ((y - 60) / 380) * 180;
📌 Смысл формулы:
-
чем ниже ветка — тем шире диапазон
x -
верх ёлки почти точка
-
низ — широкий конус
Это простая линейная интерполяция, но визуально даёт правильную форму.
3. Случайность = живость
x: 220 + (Math.random() - 0.5) * w
-
ветки не симметричны
-
нет «идеального треугольника»
-
каждая перезагрузка — немного другая ёлка
📌 Именно случайность убирает «компьютерность».
4. Почему прямоугольники, а не линии?
ctx.fillRect(x, y, 2, 8);
-
дешёво по производительности
-
создаёт текстуру хвои
-
легко масштабируется
Много простых форм лучше, чем мало сложных.
💡 Огни на ёлке: фазовая анимация
Каждый огонёк — это точка со своей фазой.
const glow = (Math.sin(t * 0.003 + phase) + 1) / 2;
📌 Что здесь происходит:
-
t— время отrequestAnimationFrame -
sin()создаёт плавное дыхание -
phase— индивидуальное смещение
В итоге:
-
огни не мигают одновременно
-
нет резких скачков
-
создаётся эффект «живой гирлянды»
Клик по ёлке — волна света
clickWave += 1;
clickWave *= 0.92;
-
при клике усиливается свечение
-
затем экспоненциально затухает
-
создаёт ощущение реакции на пользователя
📌 Это state-based animation, а не одноразовый эффект.
🌟 Звезда на макушке
ctx.shadowBlur = 30;
ctx.shadowColor = 'gold';
Звезда — это:
-
маленький круг
-
большое размытие
-
эффект свечения без сложной геометрии
Принцип: свет важнее формы.
💡 Гирлянды: синус вместо физики
Гирлянды не «висят», а математически колеблются.
y = baseY + Math.sin(x * 0.01) * amplitude;
-
синус = провисание
-
небольшая амплитуда = реализм
-
никаких расчётов верёвок или масс
📌 Глаз верит синусу больше, чем физике.
❄️ Снег: почему не Canvas
Снег реализован через DOM + CSS, потому что:
-
не требует сложной логики
-
браузер оптимизирует анимации
-
не мешает Canvas-рендеру
Это осознанный выбор, а не упрощение.
🎆 Фейерверки: частицы + гравитация
Каждая частица:
vy += 0.05; // псевдо-гравитация
alpha -= 0.015;
-
движение
-
падение
-
затухание
Никакой физики — только визуальное правдоподобие.
🧠 Общий принцип анимаций проекта
Во всём проекте используется один подход:
Много простых элементов + плавная математика + небольшая случайность
Это:
-
дешево по ресурсам
-
легко расширяется
-
выглядит «живым»
📌 Почему это хороший пример для обучения
Этот проект отлично показывает:
-
как мыслить процедурно
-
как заменять сложные модели простыми формулами
-
как делать визуал без библиотек
-
как управлять состоянием анимации
🌐 Файл mysite.txt — серверная логика (Nginx)
Это ключевая особенность проекта, которая выводит его за рамки обычного фронтенда.
🔐 HTTPS и HTTP/2
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/...
-
защищённое соединение
-
бесплатный сертификат Let’s Encrypt
-
поддержка HTTP/2
🔁 Редирект HTTP → HTTPS
return 301 https://$host$request_uri;
Пользователь никогда не остаётся на небезопасной версии.
🧠 Подстановка IP без JavaScript
sub_filter
sub_filter
'И готов к демонстрации ✨'
'Ваш IP: $remote_addr';
🔹 HTML-файл не меняется
🔹 JavaScript не нужен
🔹 IP подставляется на лету сервером
Это редкий и очень показательный приём.
📡 Маршрут /myip
location /myip {
return 200 "$remote_addr";
}
Позволяет получить IP напрямую:
https://site/myip
Полезно для:
-
диагностики
-
тестирования
-
API
-
сетевых проверок
⚙️ Производительность
gzip on;
gzip_types text/css application/javascript;
-
CSS и JS сжимаются
-
HTML не сжимается, чтобы работал
sub_filter -
грамотный баланс скорости и функциональности
| Критерий | Оценка |
|---|---|
| Frontend | ✅ |
| Canvas | ✅ |
| Адаптивность | ✅ |
| Чистота кода | ✅ |
| HTTPS | ✅ |
| Nginx-логика | ✅ |
| IP без JS | ✅ |
| Демонстрационная ценность | ✅ |
| ## 🧩 Итог |
Это показательный, умный и компактный проект, который:
-
красиво выглядит
-
технически грамотен
-
демонстрирует сервер не словами, а делом
-
отлично подходит как:
-
демо-страница сервера
-
учебный проект
-
портфолио
-
новогодняя открытка для IT-людей
-